﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour {

    [SerializeField]
    private Board board;

    // 选择中的拼图
    private Piece selectedPiece;

    // 枚举.
    private enum GameState {
        // 等待输入
        Idle,
        // 移动拼图
        PieceMove,
        // 检查匹配
        MatchCheck,
        // 删除匹配
        DeletePiece,
        // 填充新拼图
        FillPiece,

        // 等待状态（消除和填充拼图）
        Wait
    }

    private GameState currentState = GameState.Idle;

    // [SerializeField]
    // private Text stateText;

    // 多少个拼图相连算匹配
    public const int MachingCount = 3;

    // 选择中宝珠的透明度
    private const float SelectedPieceAlpha = 0.5f;

    // 当前正在选择的宝珠对象（显示用、不进Broad里的borad棋盘中，所以没有任何判定）
    private GameObject selectedPieceObject;

    [SerializeField]
    private UIManager uIManager;

    private void Start () {

        // 可以自定义棋盘的规则和大小
        board.InitializeBoard (6, 5);

        // StartCoroutine(wait5() );

    }

    // IEnumerator wait5() {
    //     yield return new WaitForSeconds(5);

    //     Debug.Log("5秒后");
    // }

    // 游戏的主流程
    private void Update () {
        switch (currentState) {

            case GameState.Idle:
                // 等待输入
                Idle ();
                break;
            case GameState.PieceMove:
                // 移动拼图
                PieceMove ();
                break;
            case GameState.MatchCheck:
                // 三消匹配
                MatchCheck ();
                break;
            case GameState.DeletePiece:
                // 删除拼图
                DeletePiece ();
                break;
            case GameState.FillPiece:
                // 掉落匹配
                FillPiece ();
                break;
            default:
                break;
        }
        // stateText.text = "当前状态:" + currentState.ToString ();

        // 通过UIManager更新状态文本信息
        uIManager.SetStatusText("当前状态:" + currentState.ToString ());
    }

    //-------------------------------------------------------
    // Private Function
    //-------------------------------------------------------
    // 检查玩家是否有选择拼图、选择拼图之后，让系统进入选择状态
    private void Idle () {
        // 当我们进行点击
        if (Input.GetMouseButtonDown (0)) {

            uIManager.ResetCombo();

            // 寻找出玩家正在选择的拼图
            /*// ver.1
            selectedPiece = board.GetStartPiece (Input.mousePosition);

            // 使其半透明
            selectedPiece.SetPieceAlpha(0.5f);

            // 如果玩家选择到了拼图 进入拼图移动状态
            if (selectedPiece != null) {
                // 状态迁移至拼图的移动
                currentState = GameState.PieceMove;
            }*/

            // 封装一下点击选择宝珠
            SelectPiece();

        }
    }

    private void SelectPiece () {

        selectedPiece = board.GetStartPiece (Input.mousePosition);

        // ver.1
        /*// 使其半透明
        selectedPiece.SetPieceAlpha(0.5f);*/

        // 如果玩家选择到了拼图 进入拼图移动状态
        if (selectedPiece == null) {
            // 没有选择 不执行
            return;
        }

        // 生成一个大一号的被选择中的拼图
        var piece = board.InstantiatePiece (Input.mousePosition);
        piece.SetKind (selectedPiece.GetKind ());
        piece.SetSize ((int) (board.pieceWidth * 1.2f));
        piece.SetPieceAlpha (SelectedPieceAlpha);
        // 作为一个对象登录，并销毁
        selectedPieceObject = piece.gameObject;
        // 状态迁移至拼图的移动
        currentState = GameState.PieceMove;
    }

    // 玩家选择了拼图时的处理、如果检查到输入结束之后，系统进入检查棋盘状态
    private void PieceMove () {
        if (Input.GetMouseButton (0)) {
            // 输入还未结束
            // 检查距离点击最近的一个拼图
            var piece = board.GetNearestPiece (Input.mousePosition);
            // 如果不是同一个拼图
            if (piece != selectedPiece) {
                // 选择中的拼图和拼图交换位置
                board.SwitchPiece (selectedPiece, piece);
            }
            // 选择中的宝珠靠上一点显示
            selectedPieceObject.transform.position = Input.mousePosition + Vector3.up;
        } else if (Input.GetMouseButtonUp (0)) {
            // 输入结束
            // 控制中的宝珠颜色回归
            selectedPiece.SetPieceAlpha (1.0f);
            // 销毁掉选择中显示的宝珠
            Destroy(selectedPieceObject);
            currentState = GameState.MatchCheck;
        }
    }

    // 检查棋盘上是否有匹配的拼图
    private void MatchCheck () {
        if (board.HasMatch ()) {
            // 如果有匹配拼图进入删除
            currentState = GameState.DeletePiece;
        } else {
            // 回到初始状态
            currentState = GameState.Idle;
        }
    }

    /// <summary>
    /// 删除已被匹配的拼图
    /// </summary>
    private void DeletePiece () {
        // ver.1无待机处理 
        // board.DeleteMatchPiece ( );
        // 迁移至填充棋盘
        // currentState = GameState.FillPiece;

        // 进入等待
        currentState = GameState.Wait;

        // ver.2无待机处理 
        StartCoroutine (board.DeleteMatchPiece (

            // 重点2.回调
            // 回调 当board.DeleteMatchPiece执行完毕的时候，执行GameManaer里的切换状态
            // 1.这里采用的是labda函数的方式声明这个回调函数
            () => currentState = GameState.FillPiece
            // 2.回调的处理超过一行时
            // () => {
            //     // https://baike.baidu.com/item/%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0
            //     Debug.Log("回调发生");
            //     currentState = GameState.FillPiece;
            // }
            // 3.直接引用函数方法
            //ChangeToFill

        ));
    }

    // private void ChangeToFill() {
    //      currentState = GameState.FillPiece;
    // }

    // 补充盘面上被删除的拼图
    private void FillPiece () {
        // ver.1 同步处理
        //board.FillPiece ();
        // 迁移至配对检查
        //currentState = GameState.MatchCheck;

        // ver.2 异步，加入待机处理

        // 进入等待
        currentState = GameState.Wait;
        
        StartCoroutine (board.FillPiece (() =>
            currentState = GameState.MatchCheck
        ));
    }
}